/**
 * 遍历树的每个节点
 * @param tree 树
 * @param cb 回调函数
 */
export const treeForEach = (
  tree: any[] = [],
  cb: (item?: any) => void,
  childrenField = 'children'
) => {
  tree.forEach((item: any) => {
    cb(item)
    if (item[childrenField]?.length) {
      treeForEach(item[childrenField], cb)
    }
  })
}

/**
 * 扁平数组转树结构
 * @param flatArr
 * @param options 树结构配置
 */

export const flatToTree = (
  flatArr: any[] = [],
  options?: {
    primaryKeyField?: string
    parentField?: string
    childrenField?: string
  }
) => {
  const {
    primaryKeyField = 'id',
    parentField = 'parentId',
    childrenField = 'children'
  } = options || {}
  const result: any[] = []

  const dictionary = flatArr.reduce((pre, cur) => {
    pre[cur.id] = { ...cur, children: [] }
    return pre
  }, {})

  flatArr.forEach((item) => {
    const parent = dictionary[item[parentField]]
    if (parent) parent[childrenField].push(dictionary[item.id])
    else result.push(dictionary[item[primaryKeyField]])
  })
  return result
}

/**
 * 树结构转扁平数组
 * @param tree 树
 * @param options 树结构配置
 */
export const treeToFlat = (
  tree: any[] = [],
  options?: {
    primaryKeyField?: string
    parentField?: string
    childrenField?: string
  }
) => {
  const {
    primaryKeyField = 'id',
    parentField = 'parentId',
    childrenField = 'children'
  } = options || {}
  function cb(prev, curr) {
    prev.push({
      ...curr,
      [childrenField]: null
    })
    if (curr[childrenField]?.length) {
      curr[childrenField].forEach((v) => {
        v[parentField] = curr[primaryKeyField]
        cb(prev, v)
      })
    }
    return prev
  }
  return tree.reduce(cb, [])
}
